////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_SQUARE_H__
#define __WN_SQUARE_H__

#include "WNCore/inc/WNTypes.h"
#include "WNMath/inc/WNPoint2.h"
#include "WNMath/inc/WNVector2.h"

namespace WNMath {
    class WNBounds2;
    class WNCircle;

    class WNRectangle {
    public:
        WNRectangle();
        explicit WNRectangle(const WN_FLOAT32* _f);
        explicit WNRectangle(const WNPoint2& _location, const WNVector2& _extents, WN_FLOAT32 _rotation);
        explicit WNRectangle(WN_FLOAT32 _x1, WN_FLOAT32 _y1, WN_FLOAT32 _x2, WN_FLOAT32 _y2, WN_FLOAT32 _rotation);

        WN_BOOL operator == (const WNRectangle& _rectangle) const;
        WN_BOOL operator != (const WNRectangle& _rectangle) const;

        WN_VOID Zero();
        WN_VOID Expand(WN_FLOAT32 _amount);
        WN_BOOL Expand(const WNPoint2& _point, WN_BOOL _anchor = WN_FALSE);
        WN_BOOL Expand(const WNBounds2& _bounds, WN_BOOL _anchor = WN_FALSE);
        WN_BOOL Expand(const WNRectangle& _rectangle, WN_BOOL _anchor = WN_FALSE);
        WN_BOOL Expand(const WNCircle& _circle, WN_BOOL _anchor = WN_FALSE);
        WN_VOID Translate(WN_FLOAT32 _x, WN_FLOAT32 _y);
        WN_VOID Translate(const WNVector2& _vector);
        WN_VOID Rotate(WN_FLOAT32 _angle);
        WN_VOID Scale(WN_FLOAT32 _scale);
        WN_VOID Scale(WN_FLOAT32 _x, WN_FLOAT32 _y);
        WN_VOID Scale(const WNVector2& _scale);

        WN_FLOAT32 Length() const;
        WN_FLOAT32 Width() const;
        WN_FLOAT32 Perimeter() const;
        WN_FLOAT32 Area() const;

        WN_BOOL IsZero() const;
        WN_BOOL IsInsideOut() const;

        WN_VOID Set(const WN_FLOAT32* _f);
        WN_VOID Set(const WNPoint2& _location, WNVector2& _extents, WN_FLOAT32 _rotation);
        WN_VOID Set(WN_FLOAT32 _x1, WN_FLOAT32 _y1, WN_FLOAT32 _x2, WN_FLOAT32 _y2, WN_FLOAT32 _rotation);

        WNRectangle GetExpanded(WN_FLOAT32 _amount) const;
        WNRectangle GetExpanded(const WNPoint2& _point, WN_BOOL _anchor = WN_FALSE) const;
        WNRectangle GetExpanded(const WNBounds2& _bounds, WN_BOOL _anchor = WN_FALSE) const;
        WNRectangle GetExpanded(const WNCircle& _circle, WN_BOOL _anchor = WN_FALSE) const;
        WNRectangle GetExpanded(const WNRectangle& _rectangle, WN_BOOL _anchor = WN_FALSE) const;
        WNRectangle GetTranslated(WN_FLOAT32 _x, WN_FLOAT32 _y) const;
        WNRectangle GetTranslated(const WNVector2& _vector) const;
        WNRectangle GetRotated(WN_FLOAT32 _angle) const;
        WNRectangle GetScaled(WN_FLOAT32 _scale) const;
        WNRectangle GetScaled(WN_FLOAT32 _x, WN_FLOAT32 _y) const;
        WNRectangle GetScaled(const WNVector2& _scale) const;
        WN_VOID GetPoints(WNPoint2* _points) const;

    public:
        WNPoint2 location;
        WNVector2 extents;
        WN_FLOAT32 rotation;
    };
}

#endif // __WN_SQUARE_H__